<?php
/**
 * ClassName:参数处理器
 * @auditor:leijunxiang
 * @time 2025/4/8 15:12
 */

namespace app\tool\word;

use app\factory\Factory;
use app\model\freightForward\WarehousePriceHistory;
use app\modelOperate\freightForward\ChannelDetailOpe;
use app\modelOperate\freightForward\WarehousePriceHistoryOpe;
use app\modelOperate\freightForward\WarehousePriceOpe;
use app\tool\ToolBase;
use think\facade\Log;

class ParamHandle extends ToolBase
{
    /**
     * (true/false)开始处理(数据定位对象,excel对象，表格数据对象)
     */
    public function startHandle($dataPositionObj, $excelObj, $tableDataObj)
    {
        if (empty($dataPositionObj) || empty($excelObj) || empty($tableDataObj)) {
            return false;
        }
        $this->init();
        //获取左上角
        $leftTop = $dataPositionObj->getLeftTopCoord();
        //获取右下角
        $rightBottom = $dataPositionObj->getRightTopCoord();
        $tool = app(WordHandleTool::class);
        //生成时间
        $time = time();
        for ($row = $leftTop[0]; $row <= $rightBottom[0]; $row++) {
            //(字符串)开始处理(excel对象,行,列)
            $areaName = $tool->startHandle($excelObj, $row, $leftTop[1]);
            //获取名称数组
            $nameAttr = $this->getNameAttr($areaName);
            if (empty($nameAttr)) {
                $this->errCode = FAIL;
                $this->errMsg = "获取区域名称失败，请重试!";
                break;
            }
            foreach ($nameAttr as $areaName) {
                if($areaName==""){
                    continue;
                }
                //校验名称是否合法
                $flag = $this->verifyName($areaName);
                if(!$flag){
                    $this->errCode = FAIL;
                    $this->errMsg = "检测到名称中有，违规字符，位置：".$leftTop[1].$row."(". implode(",",EXCEPTION_SPLIT).")";
                    return false;
                }
                //校验名称是否已存在
                $channelId = $tableDataObj->getChannelId();
                $detailId = $this->verifyIsTrue($areaName, $channelId);
                //更新标识
                $updateFlag = true;
                if (empty($detailId)) {
                    $updateFlag = false;
                    //(详情id)保存渠道详情信息(表格数据对象,区域名称)
                    $detailId = $this->saveChannelDetailMsg($tableDataObj, $areaName);
                    if (!$detailId) {
                        $this->errCode = FAIL;
                        $this->errMsg = "保存仓库详情失败，请重试!";
                        break;
                    }
                }
                //获取重量队列
                $i = 0;
                //仓库数组
                $warehouseArr = [];
                $weightList = $tableDataObj->getWeightList();
                //保存仓库价格信息
                for ($col = chr(ord($leftTop[1]) + 1); $col <= $rightBottom[1]; $col++) {
                    //获取价格
                    $price = $tool->startHandle($excelObj, $row, $col);
                    //保留小数点后一位
                    $price = round($price, 1);
                    //校验重量是否存在(详情id,重量名称)
                    $arr = $this->verifyWeight($detailId, $weightList[$i]);
                    if ($arr) {
                        //是否本次更新
                        if ($arr[0]['time'] == $time) {
                            //是
                            $oldPrice = $arr[0]['price'];
                            if ($price < $oldPrice) {
                                //更新仓库价格信息(详情id,重量表名,价格,时间)
                                $this->updatePriceMsg($detailId, $weightList[$i], $price, $time);
                                //保存仓库历史价格信息(详情id,重量,价格)
                                $this->savePriceHistory($detailId, $weightList[$i], $price, $time);
                            }
                        } else {
                            //不是
                            //更新仓库价格信息(详情id,重量表名,价格,时间)
                            $this->updatePriceMsg($detailId, $weightList[$i], $price, $time);
                            //保存仓库历史价格信息(详情id,重量,价格)
                            $this->savePriceHistory($detailId, $weightList[$i], $price, $time);
                        }
                    } else {
                        //保存仓库价格信息(详情id,重量,价格,时间)
                        $this->savePriceMsg($detailId, $weightList[$i], $price, $time);
                        //保存仓库历史价格信息(详情id,重量,价格)
                        $this->savePriceHistory($detailId, $weightList[$i], $price, $time);
                    }

                    //设置是否保存数据
                    $tableDataObj->setIsSaveTrue(true);
                    $i++;
                }
            }
        }
        return $this->isGoOn();
    }


    //(详情id)保存渠道详情信息(表格数据对象,区域名称)
    protected function saveChannelDetailMsg($tableDataObj, $areaName)
    {
        if (!$this->isGoOn()) {
            return "";
        }
        $channelId = $tableDataObj->getChannelId();
        //保存区域名称
        $tableDataObj->setAreaName($areaName);
        $ope = app(ChannelDetailOpe::class);
        $detailId = Factory::createUniqueNumber();
        $arr = [
            //渠道详情id
            "detailId" => $detailId,
            //渠道id
            "channelId" => $channelId,
            //区域名称
            "areaName" => $areaName,
            //时间
            "time" => time()
        ];
        $flag = $ope->saveData($arr);
        if (!$flag) {
            return "";
        }
        return $detailId;
    }

    /**
     * 保存仓库价格信息(详情id,重量,价格)
     */
    public function savePriceMsg($detailId, $weightName, $price, $time)
    {
        //获取重量
        // 正则提取连续的数字
        $weight = preg_replace('/[^0-9]/', '', $weightName);
        $weight = trim($weight); // 去除前后空格

        $ope = app(WarehousePriceOpe::class);
        $warehouseId = Factory::createUniqueNumber();
        $arr = [
            "warehouseId" => $warehouseId,
            "detailId" => $detailId,
            "weight" => $weight,
            "price" => $price,
            "weightName" => $weightName,
            "time" => $time
        ];
        $ope->saveData($arr);
    }

    /**
     * 校验名称是否已存在(区域名称,渠道id)
     */
    protected function verifyIsTrue($areaName, $channelId)
    {
        $ope = app(ChannelDetailOpe::class);
        //根据区域名称查询id
        $id = $ope->selectIdByAreaName($areaName, $channelId);
        return $id;
    }

    /**
     * 校验重量是否存在(详情id,重量名称)
     * @return void
     */
    protected function verifyWeight($detailId, $weightName)
    {
        $arr = [];
        if (!$this->isGoOn()) {
            return [];
        }
        $ope = app(WarehousePriceOpe::class);
        // 根据详情id和重量查询数据(详情id,重量名称)
        $arr = $ope->selectDataByDetailIdAndWeightName($detailId, $weightName);
        return $arr;
    }

    /**
     * 更新仓库价格信息(详情id,重量表名,价格,时间)
     */
    protected function updatePriceMsg($detailId, $weight, $price, $time)
    {
        if (!$this->isGoOn()) {
            return;
        }
        $ope = app(WarehousePriceOpe::class);
        $num = $ope->updatePriceByDetailIdAndWeight($detailId, $weight, $price, $time);
        return $num;
    }

    /**
     * 保存仓库历史价格信息(详情id,重量,价格)
     */
    protected function savePriceHistory($detailId, $weightName, $price, $time)
    {
        if (!$this->isGoOn()) {
            return;
        }

        //获取重量
        // 正则提取连续的数字
        $weight = preg_replace('/[^0-9]/', '', $weightName);
        $weight = trim($weight); // 去除前后空格

        $ope = app(WarehousePriceHistoryOpe::class);
        $historyId = Factory::createUniqueNumber();
        $data = $historyId;
        $arr = [
            "historyId" => $historyId,
            "detailId" => $detailId,
            "weight" => $weight,
            "price" => $price,
            "weightName" => $weightName,
            "time" => $time
        ];
        $ope->saveData($arr);
        return $data;
    }

    /**
     * 获取仓库价格(仓库名称，重量，价格，&仓库数组)
     */
    protected function getPrice($name, $weight, $price, &$warehouseArr)
    {
        $data = 0;
        $oldPrice = @$warehouseArr[$name][$weight];
        if (empty($oldPrice)) {
            //保存价格
            $warehouseArr[$name][$weight] = $price;
            $data = $price;
        } else {
            if ($price < $oldPrice) {
                $data = $price;
                //保存低的价格
                $warehouseArr[$name][$weight] = $price;
            } else {
                //价格高于历史价格，不保存
                $data = $oldPrice;
            }
        }
        return $data;
    }

    /**
     * 获取名称数组(名称)
     */
    protected function getNameAttr($name)
    {
        $splits = NAME_SPLIT;
        $nameArr = [];
        foreach ($splits as $split) {
            $nameArr = explode($split, $name);
            if (count($nameArr) > 1) {
                break;
            }
        }
        return $nameArr;
    }

    /**
     * 校验名称是否合法(名称)
     * @param $areaName
     * @return void
     */
    private function verifyName($areaName)
    {
        $exp = EXCEPTION_SPLIT;
        //名称中有异常字段，返回报错
        foreach ($exp as $e){
            if (strpos($areaName, $e) !== false) {
                return false;
            } else {
                return true;
            }
        }
    }

}